/*
==========================================================
DX490a - Summer 2010
Instructor: Stelios Manousakis
==========================================================
Class 7.2:
A ProcMod & control mapping example
Contents:
• A sound example
==========================================================
*/
// ================= PROCMOD WITH HID CONTROL =================
// This example builds on example 7.1. The synthdef has been converted to a procmod, and a SpaceNavigator device is used to control the sound. The buttons turn the procmod on and off, and the 6 axes control various aspects of the synthesis.
(
// === • Interfacing connections: ===
// The first thing you need to do is look at the devices that are connected to your machine:
GeneralHID.buildDeviceList;
// You can make a list of the devices:
d = GeneralHID.deviceList;
// You then can pick a specific device and open it for usage:
a = GeneralHID.open(d[2]); // maybe you'd need to change that...
//// start the eventloop if its not running already:
GeneralHID.startEventLoop;
//a.debug_(false)
// === • Sound synthesis ===
// load a simple FM synth, no mapping inside the synth
~combfm = CtkSynthDef( \combFM, { |outbus = 0, freq = 440, harm = 1, modix = 1, delay = 0.1, pan = 0, amp = 0.5, envbus, freqMul = 1|
var car, mod, out, dev, modfreq;
freq = freq * freqMul;
modfreq = freq * harm;
dev = modix * modfreq;
mod = SinOsc.ar(modfreq, 0, dev);
car = SinOsc.ar(freq + (mod * modix));
out = Out.ar(outbus, (Pan2.ar(CombC.ar(car, 0.5, delay, 0.5), pan, amp) * In.kr(envbus)));
});
/// === • mapping stuff ===
// create as many control buses as the parameters of the controlling interface
~ctrl = 6.collect({CtkControl.play});
// create some envelopes to handle the parameter mapping as you wish
~panEnv = Env([-1, 1], [1], \lin);
~ampEnv = Env([0.001, 0.7], [1], 3);
~modEnv = Env([1, 50], [1], 2);
~freqEnv = Env([40, 3000], [1], 4);
//~cutEnv = Env([50, 8000], [1], 2);
~delEnv = Env([0, 0.5], [1], 2);
~harmEnv = Env([0.1, 10], [1], 2);
// Name the device's controls:
a.add(\leftBtn, [1, 1]);
a.add(\rightBtn, [1, 2]);
a.add(\r_l_pan, [3, 48]);
a.add(\u_d_pan, [3, 49]);
a.add(\push_pull, [3, 50]);
a.add(\tilt, [3, 51]);
a.add(\spin, [3, 52]);
a.add(\roll, [3, 53]);
// within each slot's action: fill the appropriate CtkControl bus with the values coming in from the device slot:
a[\r_l_pan].action_({|val| ~ctrl[0].set([~panEnv[val.value]])});
a[\u_d_pan].action_({|val| ~ctrl[1].set([~modEnv[val.value]])});
a[\push_pull].action_({|val| ~ctrl[2].set([~ampEnv[val.value]])});
a[\tilt].action_({|val| ~ctrl[3].set([~delEnv[val.value]])});
a[\spin].action_({|val| ~ctrl[4].set([~freqEnv[val.value]])});
a[\roll].action_({|val| ~ctrl[5].set([~harmEnv[val.value]])});
// use the buttons to turn on/off the procmod
a[\leftBtn].action_({|val| if(val.value == 1, {p.play; q.release})}); // left button starts the procmod
a[\rightBtn].action_({|val| if(val.value == 1, {q.play; p.release})}); // right button stops it
// === • the procmod ===
p = ProcMod.new(Env([0, 1, 0], [0.1, 3], \sin, 1), id: \testHID, server: s)
.function_({arg group, envbus, server;
var note;
note = ~combfm.new(target:group)
.freqMul_(1)
.pan_(~ctrl[0]).modix_(~ctrl[1]).amp_(~ctrl[2]).delay_(~ctrl[3]).freq_(~ctrl[4]).harm_(~ctrl[5])
.envbus_(envbus).play;
});
// === • the procmod ===
q = ProcMod.new(Env([0, 1, 0], [0.1, 3], \sin, 1), id: \testHID, server: s)
.function_({arg group, envbus, server;
var note;
note = ~combfm.new(target:group)
.freqMul_(0.1)
.pan_(~ctrl[0]).modix_(~ctrl[1]).amp_(~ctrl[2]).delay_(~ctrl[3]).freq_(~ctrl[4]).harm_(~ctrl[5])
.envbus_(envbus).play;
});
)
/*
LAB: Make one or more procmods with your own synthdefs, and control them in real-time with a device
*/